using BepuUtilities.Collections;
using BepuUtilities.Memory;
using System.Diagnostics;
using System.Runtime.CompilerServices;

namespace BepuPhysics.Trees
{


    partial struct Tree
    {
        unsafe void CollectSubtreesForNodeDirect(int nodeIndex, int remainingDepth,
            ref QuickList<int> subtrees, ref QuickQueue<int> internalNodes, out float treeletCost)
        {
            internalNodes.EnqueueUnsafely(nodeIndex);

            treeletCost = 0;
            ref var node = ref Nodes[nodeIndex];
            ref var children = ref node.A;

            --remainingDepth;
            if (remainingDepth >= 0)
            {
                for (int i = 0; i < 2; ++i)
                {
                    ref var child = ref Unsafe.Add(ref children, i);
                    if (child.Index >= 0)
                    {
                        treeletCost += ComputeBoundsMetric(ref child.Min, ref child.Max);
                        float childCost;
                        CollectSubtreesForNodeDirect(child.Index, remainingDepth, ref subtrees, ref internalNodes, out childCost);
                        treeletCost += childCost;
                    }
                    else
                    {
                        // 这是一片树叶,马上把它加到子树上。
                        subtrees.AddUnsafely(child.Index);
                    }
                }
            }
            else
            {
                // 递归已经触底。添加每个孩子。
                // 同样,请注意,即使这些节点是内部的,也不会考虑它们的小树成本。
                // 这是因为由于优化,子树内部节点不能更改大小。
                for (int i = 0; i < 2; ++i)
                {
                    subtrees.AddUnsafely(Unsafe.Add(ref children, i).Index);
                }
            }
        }

        public unsafe void CollectSubtreesDirect(int nodeIndex, int maximumSubtrees,
            ref QuickList<int> subtrees, ref QuickQueue<int> internalNodes, out float treeletCost)
        {
            var maximumDepth = SpanHelper.GetContainingPowerOf2(maximumSubtrees) - 1;
            Debug.Assert(maximumDepth > 0);
            // 成本不包括树根,因为优化不能改变树根的大小。因此,不必费心将其包含在treeleCost中。

            CollectSubtreesForNodeDirect(nodeIndex, maximumDepth, ref subtrees, ref internalNodes, out treeletCost);


        }




    }
}
